#include <myhead.h>
#include "mypkg.h"

int pkg_pack_buf(char* buf, msg_type_t msg_type, int argc, ...){
	va_list ap;
	va_start(ap, argc);
	//计算p_contont需要开辟的空间
	
	int start=0;
	buf[start++]=(char)0x55;
	//报文类型
	memcpy(buf+start, &msg_type, sizeof(int));
	start+=sizeof(int);
	//报文长度
	start+=4;//最后在打包	
	//报文内容
	for(int i=0; i<argc; i++){
		char* arg = va_arg(ap, char *);
		//字段长度
		int argLen = strlen(arg)+1;// 结尾的 /0 也计算在内
		memcpy(buf+start, &argLen, sizeof(int));
		start+=sizeof(int);
		//字段内容
		memcpy(buf+start, arg, argLen);
		start+=argLen;
	}
	//报文尾
	buf[start++]=(char)0x66;
	//报文长度
	memcpy(buf+5, &start, sizeof(int));
	//
	va_end(ap);
	return start;
}

int pkg_appendByteArr(char* buf, char* byteArr, int arrLen){
	//获取要追加的位置
	int total=0;
	memcpy(&total, buf+5, 4);

	//数据长度
	memcpy(buf+total-1, &arrLen, 4);
	total+=4;
	//数据内容
	memcpy(buf+total-1, byteArr, arrLen);
	total+=arrLen;//最后的0x66
	//报文尾
	buf[total-1]=(unsigned char)0x66;
	memcpy(buf+5, &total, 4);
	return total;
}

int pkg_unpack(char* buf, pkg_t* pkg){
	//
	memcpy(&pkg->msg_type, buf+1, 4);
	//报文总长度
	int total=0;
	memcpy(&total, buf+5, 4);
	if(total <= 10)//没有内容
		return 0;
	//p->param_arr=p_link_create();
	for(int start=9;start<total-1;){// -1 掉 报文尾
		//字段长度
		int len=0;
		memcpy(&len, buf+start, sizeof(int));
		start+=sizeof(int);
		//字段内容
		char* str=(char*)malloc(len);
		memcpy(str, buf+start, len);
		start+=len;
		pkg_add(pkg, str, len);
	}
	return 0;
}

int pkg_buf_check(char* buf, int len, char* errmsg){
    if(buf[0] != 0x55){
		strcpy(errmsg, "报文头错误");
		return -1;
	}
    int msglen=0;
    memcpy(&msglen, buf+5, 4);
    //校验报文尾
    if(msglen > len){//超过长了
		strcpy(errmsg, "报文长度字段的长度超过收取buf的总长度");
		return -1;
    }
    if(buf[msglen-1] != 0x66){
		strcpy(errmsg, "报文尾错误");
		return -1;
	}
	//TODO 报文类型不做校验了
    //bingo! 正确的报文
    return 0;
}

//************** 链表操作 ***************
pkg_t* pkg_create(){
	pkg_t* pkg=malloc(sizeof(pkg_t));
	//pkg->msg_type = msg_type;
	pkg->param_num = 0;
	//
	param_t* head=malloc(sizeof(param_t));
	head->str=NULL;
	head->next=NULL;
	//
	pkg->head = head;
	pkg->tail = pkg->head;
	return pkg;
}

void pkg_add(pkg_t* pkg, char* str, int len){
	param_t* node=malloc(sizeof(param_t));
	node->str = str;
	node->strLen = len;
	node->next=NULL;
	//
	pkg->tail->next=node;
	pkg->tail = node;
	pkg->param_num++;
}

char* pkg_get(pkg_t* pkg, int index){
	param_t* p=pkg->head->next;
	for(int i=0;i<index;i++){
		p=p->next;	
	}
	return p->str;
}

char* pkg_getbuf(pkg_t* pkg, int index, int* bufLen){
	param_t* p=pkg->head->next;
	for(int i=0;i<index;i++){
		p=p->next;	
	}
	*bufLen = p->strLen;
	return p->str;
}


void pkg_free(pkg_t* pkg){
	if(pkg == NULL)
		return;
	param_t* p=pkg->head->next;
	for(int i=0;i<pkg->param_num;i++){
		param_t* temp=p;
		p=p->next;
		//
		free(temp->str);
		free(temp);
	}
	free(pkg->head);
	free(pkg);
}






